﻿#region Using

using System;
using System.Diagnostics;
using SAPbouiCOM;
using SapFramework.Interface.Controls.Items.Base;
using SapFramework.Interface.Events;

using Form = SapFramework.Interface.Controls.Forms.Base.Form;
using Item = SapFramework.Interface.Controls.Items.Base.Item;

#endregion

namespace SapFramework.Interface.Controls.Items.Specific
{
    /// <summary>
    /// Realiza o encapsulamento de um objeto do tipo <see cref="SAPbouiCOM.ComboBox"/> da UI API do SAP Business One.
    /// </summary>
    public sealed class ComboBox : Item, SAPbouiCOM.ComboBox
    {
        #region Eventos

        /// <summary>
        /// Evento disparado quando o botão principal do mouse foi clicado duas vezes sobre um item, mas nenhuma ação foi tomada ainda.
        /// </summary>
        [Event( BoEventTypes.et_DOUBLE_CLICK )]
        public event EventBoolItem OnBeforeDoubleClick;

        /// <summary>
        /// Evento disparado quando o botão principal do mouse foi clicado duas vezes sobre um item, e qualquer ação do SBO já foi realizada.
        /// </summary>
        [Event( BoEventTypes.et_DOUBLE_CLICK )]
        public event EventVoidItem OnAfterDoubleClick;

        /// <summary>
        /// Ocorre depois que o item recebe o foco.
        /// </summary>
        [Event( BoEventTypes.et_GOT_FOCUS )]
        public event EventVoidItem OnGotFocus;

        /// <summary>
        /// Ocorre depois que o item perde o foco.
        /// </summary>
        [Event( BoEventTypes.et_LOST_FOCUS )]
        public event EventVoidItem OnLostFocus;

        /// <summary>
        /// Ocorre quando um item na ComboBox foi selecionado, porém nenhuma ação foi tomada ainda.
        /// </summary>
        [Event( BoEventTypes.et_COMBO_SELECT )]
        public event EventBoolItem OnBeforeComboSelect;

        /// <summary>
        /// Ocorre quando um item na ComboBox foi selecionado, e qualquer ação do SBO já foi executada.
        /// </summary>
        [Event( BoEventTypes.et_COMBO_SELECT )]
        public event EventVoidItem OnAfterComboSelect;

        /// <summary>
        /// Ocorre quando uma tecla for pressionado sobre a ComboBox, porém nenhuma ação foi tomada ainda.
        /// </summary>
        [Event( BoEventTypes.et_KEY_DOWN )]
        public event EventBoolItem OnBeforeKeyDown;

        /// <summary>
        /// Ocorre quando uma tecla for pressionado sobre a ComboBox, e qualquer ação do SBO já foi executada.
        /// </summary>
        [Event( BoEventTypes.et_KEY_DOWN )]
        public event EventVoidItem OnAfterKeyDown;

        /// <summary>
        /// Disparado antes da exibição do menu que ocorre quando um clique com o botão direito do mouse é feito sobre um item.
        /// </summary>
        [Event( BoEventTypes.et_RIGHT_CLICK )]
        public event EventBoolContextMenu OnBeforeRightClick;

        /// <summary>
        /// Disparado após a exibição do menu que ocorre quando um clique com o botão direito do mouse é feito sobre um item.
        /// </summary>
        [Event( BoEventTypes.et_RIGHT_CLICK )]
        public event EventVoidContextMenu OnAfterRightClick;

        #endregion

        /// <summary>
        /// Guarda uma referencia para a parte específica do item
        /// </summary>
        private readonly SAPbouiCOM.ComboBox mComboBox;

        /// <summary>
        /// Construtor
        /// </summary>
        /// <param name="aForm">O formulário ao qual o item pertence</param>
        /// <param name="aItemUniqueId">Id único do Item do Form do SAP Business One</param>
        public ComboBox( Form aForm, string aItemUniqueId ) : base( aForm, aItemUniqueId, BoFormItemTypes.it_COMBO_BOX )
        {
            mComboBox = mItem.Specific as SAPbouiCOM.ComboBox;
        }

        #region Implementation of IComboBox

        /// <summary>
        /// Realiza uma seleção de um item dentro da ComboBox, similar a forma realizada pelo usuário, e caso seja bem sucedido,
        /// dispara um evento do tipo <see cref="BoEventTypes.et_COMBO_SELECT"/>
        /// </summary>
        /// <remarks>
        /// Quando setado para <see cref="BoSearchKey.psk_ByDescription"/>, o método retorna o primeiro valor encontrado (não único).
        /// Se o método falhar em encontrar a chave em algum dos critérios de busca, ele irá procurar por um dos outros critérios:
        /// <list type="bullet">
        /// <item><see cref="BoSearchKey.psk_ByDescription"/></item>
        /// <item><see cref="BoSearchKey.psk_ByValue"/></item>
        /// </list>
        /// </remarks>
        /// <param name="aIndex">Valor procurado na ComboBox</param>
        /// <param name="aSearchKey">Informa o método de busca utilizado. Veja <see cref="BoSearchKey"/> para maiores detalhes</param>
        public void Select( object aIndex, BoSearchKey aSearchKey )
        {
            mComboBox.Select( aIndex, aSearchKey );
        }

        /// <summary>
        /// Realiza uma seleção de um item dentro da ComboBox, similar a forma realizada pelo usuário, e caso seja bem sucedido,
        /// dispara um evento do tipo <see cref="BoEventTypes.et_COMBO_SELECT"/>
        /// </summary>
        /// <remarks>
        /// <see cref="SelectExclusive"/> se difere de <see cref="Select"/> na forma que, se uma busca por um valor ou descrição não encontrar nada,
        /// uma busca com os outros valores de <see cref="BoSearchKey"/> não será realiza e uma exceção será lançada.
        /// </remarks>
        /// <exception cref="Exception">
        /// Quando nenhum valor for encontrado para realizar a seleção.
        /// </exception>
        /// <param name="aIndex">Valor procurado na ComboBox</param>
        /// <param name="aSearchKey">Informa o método de busca utilizado. Veja <see cref="BoSearchKey"/> para maiores detalhes</param>
        public void SelectExclusive( object aIndex, BoSearchKey aSearchKey )
        {
            mComboBox.SelectExclusive( aIndex, aSearchKey );
        }

        /// <summary>
        /// Referência para o objeto <see cref="ValidValues"/>, onde ficam os valores possiveis para a ComboBox
        /// </summary>
        /// <see cref="ValidValues"/>
        /// <see cref="ValidValue"/>
        public ValidValues ValidValues
        {
            get { return mComboBox.ValidValues; }
        }

        /// <summary>
        /// Recupera o <see cref="ValidValue"/> selecionado na ComboBox
        /// </summary>
        /// <remarks>
        /// Retorna nulo caso nenhum item eseja selecionado.
        /// </remarks>
        public ValidValue Selected
        {
            get { return mComboBox.Selected; }
        }

        /// <summary>
        /// Referência para o objeto <see cref="DataBind"/>, que realiza uma ligação com um:
        /// <list type="bullet">
        /// <see cref="UserDataSource"/>
        /// <see cref="DBDataSource"/>
        /// <see cref="DataTable"/>
        /// </list>
        /// </summary>
        /// <see cref="DataBind"/>
        public DataBind DataBind
        {
            get { return mComboBox.DataBind; }
        }

        /// <summary>
        /// Indica se a ComboBox possuí o fóco. Quando setado, caso o valor seja <c>true</c>, coloca o fóco no item e 
        /// caso o valor seja <c>false</c> e o item se encontre atualmente focado, passa o fóco para o próximo item que pode obter o fóco..
        /// </summary>
        public bool Active
        {
            get { return mComboBox.Active; }
            set { mComboBox.Active = value; }
        }

        /// <summary>
        /// A ordem de tabulação do item
        /// </summary>
        public int TabOrder
        {
            get { return mComboBox.TabOrder; }
            set
            {
                Debug.Assert( value > -1 );
                mComboBox.TabOrder = value;
            }
        }

        /// <summary>
        /// Retorna o valor atual selecionado na ComboBox
        /// </summary>
        /// <remarks>Retorna o <see cref="IValidValue.Value"/>, não a <see cref="IValidValue.Description"/></remarks>
        public string Value
        {
            get { return mComboBox.Value; }
        }
        #if !Debug881 && !Release881
        /// <summary>
        /// Texto que será mostrado pelas opções da CombBox quando ela for expandida.
        /// </summary>
        public BoExpandType ExpandType
        {
            get { return mComboBox.ExpandType; }
            set { mComboBox.ExpandType = value; }
        }
        #endif

        #endregion
    }
}